package controllers

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"time"
	"zero_six/house/utils"
	"zero_six/user/pb/user"

	"github.com/beego/beego/v2/core/validation"

	beego "github.com/beego/beego/v2/server/web"
)

type UserController struct {
	beego.Controller
}

// 接受数据
func (this *UserController) Login() {
	username := this.GetString("username")
	password := this.GetString("password")
	// 通过validator 验证表单
	// 验证通过以后
	// 连接RPC
	client := user.NewUserClient(utils.GetRpcClient("user.rpc").Conn())
	resp, err := client.Login(context.Background(), &user.Request{
		Username: username,
		Password: password,
	})
	if err != nil {
		log.Println(err)
		return
	}
	log.Println(resp)

	if resp.Code != 200 {
		this.Data["json"] = map[string]interface{}{
			"code": http.StatusCreated,
			"msg":  "用户名/密码错误",
		}
		this.ServeJSON()
		return
	}

	// 登录成功以后、蒋用户名保存到session
	this.SetSession("username", resp.Username)

	fmt.Println(this.GetSession("username"))
	this.SetSession("userid", resp.UserId)

	this.Data["json"] = map[string]interface{}{
		"code": http.StatusOK,
		"msg":  "ok",
	}
	this.ServeJSON()
}

func (this *UserController) SendCode() {

	// 接受数据
	mobile := this.GetString("mobile")
	valid := validation.Validation{}
	valid.Mobile(mobile, "mobile").Message("手机号格式不正确")
	if valid.HasErrors() {
		for _, err := range valid.Errors {
			this.Data["json"] = map[string]interface{}{
				"code": http.StatusOK,
				"msg":  err.Message,
			}
			this.ServeJSON()
			return
		}
	}
	var repeat_key string = fmt.Sprintf("sms:repeat_key:%s", mobile)
	var code_key string = fmt.Sprintf("sms:code_key:%s", mobile)
	var times_key string = fmt.Sprintf("sms:times_key:%s", mobile)
	// 是否重复发送
	log.Println(utils.GetRedisClient().Exists(context.Background(), repeat_key).Val())
	if utils.GetRedisClient().Exists(context.Background(), repeat_key).Val() > 0 {
		this.Data["json"] = map[string]interface{}{
			"code": http.StatusOK,
			"msg":  "已经发送过、不能重复发送",
		}
		this.ServeJSON()
		return
	}
	// 今日发送次数

	times, _ := strconv.Atoi(utils.GetRedisClient().Get(context.Background(), times_key).Val())
	if times > 2 {
		this.Data["json"] = map[string]interface{}{
			"code": http.StatusOK,
			"msg":  "今日发送次数过多",
		}
		this.ServeJSON()
		return
	}

	code := utils.GetCode(4)

	if !utils.IhuYI(mobile, code) {
		this.Data["json"] = map[string]interface{}{
			"code": http.StatusAccepted,
			"msg":  "发送失败",
		}
		this.ServeJSON()
		return
	}

	// 存储逻辑 key
	// 不能重复发送
	utils.GetRedisClient().Set(context.Background(), repeat_key, 1, time.Second*60) // 60s

	utils.GetRedisClient().Set(context.Background(), code_key, code, time.Minute*5) // 验证码

	utils.GetRedisClient().Incr(context.Background(), times_key)                                   // 自增
	utils.GetRedisClient().Expire(context.Background(), times_key, time.Second*utils.DifferTime()) //设置次数的有效期

	this.Data["json"] = map[string]interface{}{
		"code": http.StatusOK,
		"msg":  "发送成功",
		"test": code,
	}
	this.ServeJSON()
	return
}

// 手机验证登录
func (this *UserController) MobileByCodeLogin() {
	mobile := this.GetString("mobile")
	code := this.GetString("code") //用户输入的code
	// 参数验证
	valid := validation.Validation{}
	valid.Mobile(mobile, "mobile").Message("手机号格式不正确")
	valid.Length(code, 4, "code").Message("验证长度只能是4位")
	if valid.HasErrors() {
		for _, v := range valid.Errors {
			this.Data["json"] = map[string]interface{}{
				"code": http.StatusCreated,
				"msg":  v.Message,
			}
			this.ServeJSON()
			return
		}
	}

	// 判断用户是否存在
	client := user.NewUserClient(utils.GetRpcClient("user.rpc").Conn())
	resp, err := client.GetUserInfo(context.Background(), &user.RegisterRequest{
		Mobile: mobile,
	})
	if err != nil || resp.Code != http.StatusOK {
		log.Println(err)
		this.Data["json"] = map[string]interface{}{
			"code": http.StatusAccepted,
			"msg":  "用户不存在",
		}
		this.ServeJSON()
		return
	}
	log.Println(resp)

	// 验证验证码
	var code_key string = fmt.Sprintf("sms:code_key:%s", mobile)
	cache_code := utils.GetRedisClient().Get(context.Background(), code_key).Val() // 缓存中的code
	if code != cache_code {
		this.Data["json"] = map[string]interface{}{
			"code": http.StatusAccepted,
			"msg":  "验证不正确",
		}
		this.ServeJSON()
		return
	}
	// 登录成功以后、mvc（session）、生成凭证 token （header+payload+sign）
	// payload(包含token的配置、例如：有效期、签发人、签发平台、添加自定义的数据、例如用户名、用户ID、手机号)
	token, err := utils.CreateToke(&utils.CustomClaims{
		UserId:   resp.UserId,
		UserName: resp.Username,
	})
	if err != nil {
		this.Data["json"] = map[string]interface{}{
			"code": http.StatusOK,
			"msg":  "登录失败",
		}
		this.ServeJSON()
		return
	}
	fmt.Println(token)

	this.Data["json"] = map[string]interface{}{
		"code": http.StatusOK,
		"msg":  "登录成功",
		"data": map[string]interface{}{
			"token": token,
		},
	}
	this.ServeJSON()
	return
}

func (this *UserController) UpdateUserInfo() {
	fmt.Println("UserInfo")
}
